package org.dromara.bykt.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.ServletConfig;
import lombok.RequiredArgsConstructor;
import org.dromara.bykt.domain.BYKTCourse;
import org.dromara.bykt.domain.BYKTCourseOrder;
import org.dromara.bykt.domain.BYKTCourseSimulation;
import org.dromara.bykt.domain.BYKTCourseVideo;
import org.dromara.bykt.domain.bo.BYKTCourseBo;
import org.dromara.bykt.domain.bo.BYKTCourseChapterBo;
import org.dromara.bykt.domain.vo.BYKTCourseChapterListVO;
import org.dromara.bykt.domain.vo.BYKTCourseVo;
import org.dromara.bykt.mapper.BYKTCourseMapper;
import org.dromara.bykt.mapper.BYKTCourseOrderMapper;
import org.dromara.bykt.mapper.BYKTCourseSimulationMapper;
import org.dromara.bykt.mapper.BYKTCourseVideoMapper;
import org.dromara.bykt.service.IBYKTCourseChapterService;
import org.dromara.bykt.service.IBYKTCourseService;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 课程Service业务层处理
 *
 * @author Hou
 * @date 2025-06-22
 */
@RequiredArgsConstructor
@Service
public class BYKTCourseServiceImpl implements IBYKTCourseService {

    private final BYKTCourseMapper baseMapper;
    private final BYKTCourseOrderMapper courseOrderMapper;
    private final BYKTCourseVideoMapper courseVideoMapper;
    private final BYKTCourseSimulationMapper courseSimulationMapper;

    @Autowired
    private IBYKTCourseChapterService chapterService;
    @Autowired
    private ServletConfig servletConfig;

    /**
     * 查询课程
     *
     * @param id 主键
     * @return 课程
     */
    @Override
    public BYKTCourseVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询课程列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 课程分页列表
     */
    @Override
    public TableDataInfo<BYKTCourseVo> queryPageList(BYKTCourseBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BYKTCourse> lqw = buildQueryWrapper(bo);
        Page<BYKTCourseVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询符合条件的课程列表
     *
     * @param bo 查询条件
     * @return 课程列表
     */
    @Override
    public List<BYKTCourseVo> queryList(BYKTCourseBo bo) {
        LambdaQueryWrapper<BYKTCourse> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<BYKTCourse> buildQueryWrapper(BYKTCourseBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BYKTCourse> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(BYKTCourse::getId);
        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), BYKTCourse::getTitle, bo.getTitle());
        lqw.eq(StringUtils.isNotBlank(bo.getCoverImg()), BYKTCourse::getCoverImg, bo.getCoverImg());
        lqw.eq(StringUtils.isNotBlank(bo.getIntro()), BYKTCourse::getIntro, bo.getIntro());
        lqw.eq(bo.getPrice() != null, BYKTCourse::getPrice, bo.getPrice());
        lqw.eq(bo.getOriginalPrice() != null, BYKTCourse::getOriginalPrice, bo.getOriginalPrice());
        lqw.eq(bo.getCategoryId() != null, BYKTCourse::getCategoryId, bo.getCategoryId());
        lqw.like(StringUtils.isNotBlank(bo.getTeacherName()), BYKTCourse::getTeacherName, bo.getTeacherName());
        lqw.eq(StringUtils.isNotBlank(bo.getLevel()), BYKTCourse::getLevel, bo.getLevel());
        lqw.eq(bo.getStudyCount() != null, BYKTCourse::getStudyCount, bo.getStudyCount());
        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), BYKTCourse::getStatus, bo.getStatus());
        lqw.eq(bo.getSort() != null, BYKTCourse::getSort, bo.getSort());
        return lqw;
    }

    /**
     * 新增课程
     *
     * @param bo 课程
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(BYKTCourseBo bo) {
        BYKTCourse add = MapstructUtils.convert(bo, BYKTCourse.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改课程
     *
     * @param bo 课程
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(BYKTCourseBo bo) {
        BYKTCourse update = MapstructUtils.convert(bo, BYKTCourse.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BYKTCourse entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 校验并批量删除课程信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
            List<Long> nonExistingIds = new ArrayList<>(ids);
            for (Long id : nonExistingIds) {
                Long aLong = courseOrderMapper.selectCount(new LambdaQueryWrapper<BYKTCourseOrder>().eq(BYKTCourseOrder::getCourseId, id));
                if (aLong != 0) {
                    throw new ServiceException("以下课程ID订单存在，无法删除: " + id);
                }
                Long aLong1 = chapterService.queryCourseId(id);
                if (aLong1 != 0) {
                    throw new ServiceException("以下课程ID被章节使用，无法删除: " + id);
                }
                Long aLong2 = courseVideoMapper.selectCount(new LambdaQueryWrapper<BYKTCourseVideo>().eq(BYKTCourseVideo::getCourseId, id));
                if (aLong2 != 0) {
                    throw new ServiceException("以下课程ID被视频使用，无法删除: " + id);
                }
                Long aLong3 = courseSimulationMapper.selectCount(new LambdaQueryWrapper<BYKTCourseSimulation>().eq(BYKTCourseSimulation::getCourseId, id));
                if (aLong3 != 0) {
                    throw new ServiceException("以下课程ID被试卷使用，无法删除: " + id);
                }
            }
        }
        return baseMapper.deleteByIds(ids) > 0;
    }

    /**
     * 查询课程下拉
     *
     * @return 返回课程下拉
     */
    @Override
    public List<BYKTCourseVo> queryCourseList() {
        return baseMapper.selectVoList(new QueryWrapper<BYKTCourse>().lambda().eq(BYKTCourse::getStatus, "0"));
    }

    @Override
    public List<BYKTCourseVo> queryCourseLists(BYKTCourseBo byktCourseBo) {
        List<BYKTCourseVo> courseVoList = new ArrayList<>();
        QueryWrapper<BYKTCourse> courseQueryWrapper = new QueryWrapper<>();
        courseQueryWrapper.lambda().eq(BYKTCourse::getStatus, "0");

        // 设置查询条件
        if (StringUtils.isNotBlank(byktCourseBo.getTitle())) {
            courseQueryWrapper.lambda().like(BYKTCourse::getTitle, byktCourseBo.getTitle());
        }
        if (byktCourseBo.getCategoryId() != null) {
            courseQueryWrapper.lambda().eq(BYKTCourse::getCategoryId, byktCourseBo.getCategoryId());
        }

        // 查询课程列表
        List<BYKTCourseVo> byktCourseVos = baseMapper.selectVoList(courseQueryWrapper);

        if (!byktCourseVos.isEmpty()) {
            // 如果直接查询到课程，填充章节信息
            fillCourseWithChapters(courseVoList, byktCourseVos);
        } else if (StringUtils.isNotBlank(byktCourseBo.getTitle())) {
            // 如果没有查询到课程但提供了标题，尝试通过章节标题查询
            queryCoursesByChapterTitle(courseVoList, byktCourseBo.getTitle());
        }

        return courseVoList;
    }

    /**
     * 填充课程章节信息
     */
    private void fillCourseWithChapters(List<BYKTCourseVo> courseVoList, List<BYKTCourseVo> byktCourseVos) {
        for (BYKTCourseVo byktCourseVo : byktCourseVos) {
            enrichCourseVo(byktCourseVo);
            courseVoList.add(byktCourseVo);
        }
    }

    /**
     * 通过章节标题查询相关课程
     */
    private void queryCoursesByChapterTitle(List<BYKTCourseVo> courseVoList, String chapterTitle) {
        BYKTCourseChapterBo courseChapterBo = new BYKTCourseChapterBo();
        courseChapterBo.setTitle(chapterTitle);
        List<BYKTCourseChapterListVO> chapterListVOS = chapterService.queryChapterList(courseChapterBo);

        if (CollectionUtils.isNotEmpty(chapterListVOS)) {
            Set<Long> processedCourseIds = new HashSet<>();

            for (BYKTCourseChapterListVO chapterListVO : chapterListVOS) {
                Long courseId = chapterListVO.getCourseId();

                // 避免重复处理同一课程
                if (processedCourseIds.contains(courseId)) {
                    continue;
                }
                processedCourseIds.add(courseId);

                // 查询课程信息
                QueryWrapper<BYKTCourse> courseWrapper = new QueryWrapper<>();
                courseWrapper.lambda().eq(BYKTCourse::getStatus, "0")
                    .eq(BYKTCourse::getId, courseId);
                List<BYKTCourseVo> courses = baseMapper.selectVoList(courseWrapper);

                if (CollectionUtils.isNotEmpty(courses)) {
                    for (BYKTCourseVo courseVo : courses) {
                        enrichCourseVo(courseVo);
                        // 设置查询到的章节列表
                        courseVo.setChapterList(chapterListVOS.stream()
                            .filter(ch -> ch.getCourseId().equals(courseId))
                            .collect(Collectors.toList()));
                        courseVoList.add(courseVo);
                    }
                }
            }
        }
    }

    /**
     * 丰富课程VO信息
     */
    private void enrichCourseVo(BYKTCourseVo courseVo) {
        courseVo.setExpanded(true);
        courseVo.setType(1);

        // 查询章节信息
        BYKTCourseChapterBo chapterBo = new BYKTCourseChapterBo();
        chapterBo.setCourseId(courseVo.getId());
        courseVo.setChapterList(chapterService.queryChapterList(chapterBo));
    }

    @Override
    public Long selectCourseName(String courseName) {
        BYKTCourseVo byktCourseVo = baseMapper.selectVoOne(new LambdaQueryWrapper<BYKTCourse>().eq(BYKTCourse::getTitle, courseName));
        if (byktCourseVo != null) {
            return byktCourseVo.getId();
        }
        return 0L;
    }

    @Override
    public Long queryCategoryId(Long categoryId) {
        return baseMapper.selectCount(new LambdaQueryWrapper<BYKTCourse>().eq(BYKTCourse::getCategoryId, categoryId));
    }
}
